package cn.jetpiece.cloud.joss.app.modular.basics.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.jetpiece.cloud.joss.app.modular.basics.wrapper.ContentTypeWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.jetpiece.cloud.joss.api.basic.model.params.CreateContentTypeParam;
import cn.jetpiece.cloud.joss.api.basic.model.params.UpdateContentTypeParam;
import cn.jetpiece.cloud.joss.api.basic.model.query.ContentTypeQuery;
import cn.jetpiece.cloud.joss.api.basic.model.result.ContentTypeResult;
import cn.jetpiece.cloud.joss.app.core.constant.OssConstants;
import cn.jetpiece.cloud.joss.app.modular.basics.entity.ContentType;
import cn.jetpiece.cloud.joss.app.modular.basics.mapper.ContentTypeMapper;
import cn.jetpiece.cloud.joss.app.modular.basics.service.ContentTypeService;
import cn.jetpiece.cloud.joss.app.modular.object.enums.BasicExceptionEnum;
import lombok.AllArgsConstructor;
import cn.jetpiece.cloud.core.page.PageFactory;
import cn.jetpiece.cloud.model.exception.ServiceException;
import cn.jetpiece.cloud.model.page.PageResult;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;

/**
 * <p>
 * 内容类型 服务实现类
 * </p>
 *
 * @author XuJZ
 * @since 2020-09-08
 */
@Service
@AllArgsConstructor
public class ContentTypeServiceImpl extends ServiceImpl<ContentTypeMapper, ContentType> implements ContentTypeService {
    private final RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean add(CreateContentTypeParam param) {
        LambdaQueryWrapper<ContentType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContentType::getFileExtension, param.getFileExtension());
        if (super.count(wrapper) > 0) {
            throw new ServiceException(BasicExceptionEnum.CONTENT_TYPE_REPEAT);
        }
        wrapper.clear();
        wrapper.eq(ContentType::getHeaderContentType, param.getHeaderContentType());
        if (super.count(wrapper) > 0) {
            throw new ServiceException(BasicExceptionEnum.CONTENT_TYPE_REPEAT);
        }
        ContentType bean = new ContentType();
        BeanUtil.copyProperties(param, bean);
        return super.save(bean);
    }

    @Override
    public boolean update(UpdateContentTypeParam param) {
        ContentType oldBean = super.getById(param.getFileExtension());
        if (oldBean == null) {
            throw new ServiceException(BasicExceptionEnum.CONTENT_TYPE_NOT_EXISTED);
        }
        if (StrUtil.isNotEmpty(param.getHeaderContentType())) {
            LambdaQueryWrapper<ContentType> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ContentType::getHeaderContentType, param.getHeaderContentType());
            wrapper.ne(ContentType::getFileExtension, oldBean.getFileExtension());
            if (super.count(wrapper) > 0) {
                throw new ServiceException(BasicExceptionEnum.CONTENT_TYPE_REPEAT);
            }
        }
        redisTemplate.boundHashOps(OssConstants.CONTENT_TYPE).delete(oldBean.getFileExtension());
        ContentType update = BeanUtil.copyProperties(param, ContentType.class);
        update.setFileExtension(param.getFileExtension());
        return super.updateById(update);
    }

    @Override
    public boolean delete(String id) {
        ContentType bean = super.getById(id);
        if (bean == null) {
            throw new ServiceException(BasicExceptionEnum.CONTENT_TYPE_NOT_EXISTED);
        }
        redisTemplate.boundHashOps(OssConstants.CONTENT_TYPE).delete(bean.getFileExtension());
        return super.removeById(id);
    }

    @Override
    public ContentType getById(Serializable id) {
        ContentType contentType = (ContentType) redisTemplate.boundHashOps(OssConstants.CONTENT_TYPE).get(id);
        if (contentType == null) {
            contentType = super.getById(id);
            if (contentType != null) {
                redisTemplate.boundHashOps(OssConstants.CONTENT_TYPE).put(contentType.getFileExtension(), contentType);
            }
        }
        return contentType;
    }

    @Override
    public PageResult<ContentTypeResult> page(ContentTypeQuery param) {
        LambdaQueryWrapper<ContentType> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(param.getFileExtension())) {
            wrapper.like(ContentType::getFileExtension, param.getFileExtension());
        }
        if (StrUtil.isNotEmpty(param.getHeaderContentType())) {
            wrapper.like(ContentType::getHeaderContentType, param.getHeaderContentType());
        }
        IPage<ContentType> iPage = PageFactory.defaultPage();
        IPage<ContentType> page = super.page(iPage, wrapper);
        return new ContentTypeWrapper(page).setWrapper(param.getWrapper()).wrapPageResult();
    }

    @Override
    public String getContentType(String fileExtension) {
        ContentType contentType = getById(fileExtension.replace(OssConstants.SUFFIX_NAME_SEPARATE, ""));
        if (contentType == null) {
            return "application/octet-stream";
        }
        return contentType.getHeaderContentType();
    }
}
